@@ -74,6 +74,8 @@ gem 'slack-notifier', '~> 0.5.0' |
||
74 | 74 |
|
75 | 75 |
gem 'therubyracer', '~> 0.12.1' |
76 | 76 |
|
77 |
+gem 'mqtt' |
|
78 |
+ |
|
77 | 79 |
group :development do |
78 | 80 |
gem 'binding_of_caller' |
79 | 81 |
gem 'better_errors' |
@@ -160,6 +160,7 @@ GEM |
||
160 | 160 |
mime-types (1.25.1) |
161 | 161 |
mini_portile (0.5.3) |
162 | 162 |
minitest (5.3.3) |
163 |
+ mqtt (0.2.0) |
|
163 | 164 |
multi_json (1.9.3) |
164 | 165 |
multi_xml (0.5.5) |
165 | 166 |
multipart-post (2.0.0) |
@@ -341,6 +342,7 @@ DEPENDENCIES |
||
341 | 342 |
kaminari (~> 0.15.1) |
342 | 343 |
kramdown (~> 1.3.3) |
343 | 344 |
liquid (~> 2.6.1) |
345 |
+ mqtt |
|
344 | 346 |
mysql2 (~> 0.3.15) |
345 | 347 |
nokogiri (~> 1.6.1) |
346 | 348 |
protected_attributes (~> 1.0.7) |
@@ -0,0 +1,112 @@ |
||
1 |
+# encoding: utf-8 |
|
2 |
+require "mqtt" |
|
3 |
+ |
|
4 |
+module Agents |
|
5 |
+ class MqttAgent < Agent |
|
6 |
+ description <<-MD |
|
7 |
+ The MQTT agent allows both publication to an MQTT topic and subscription to an MQTT topic. |
|
8 |
+ |
|
9 |
+ Setup your own broker (http://jpmens.net/2013/09/01/installing-mosquitto-on-a-raspberry-pi/) or connect to a cloud service (www.cloudmqtt.com). |
|
10 |
+ |
|
11 |
+ MQTT is a generic transport protocol for machine to machine communication. |
|
12 |
+ |
|
13 |
+ You can do things like: |
|
14 |
+ |
|
15 |
+ * Publish to [RabbitMQ](http://www.rabbitmq.com/mqtt.html) |
|
16 |
+ * Run [OwnTracks, a location tracking tool](http://owntracks.org/) for iOS and Android |
|
17 |
+ * Subscribe to your home automation setup like [Ninjablocks](http://forums.ninjablocks.com/index.php?p=/discussion/661/today-i-learned-about-mqtt/p1) or [TheThingSystem](http://thethingsystem.com/dev/supported-things.html) |
|
18 |
+ |
|
19 |
+ Simply choose a topic (think email subject line) to publish/listen to, and configure your service. |
|
20 |
+ |
|
21 |
+ Hints: |
|
22 |
+ Many services run mqtts (mqtt over SSL) often with a custom certificate. |
|
23 |
+ |
|
24 |
+ You'll want to download their cert and install it locally, specifying the ```certificate_path``` configuration. |
|
25 |
+ |
|
26 |
+ |
|
27 |
+ Example configuration: |
|
28 |
+ |
|
29 |
+ <pre><code>{ |
|
30 |
+ 'uri' => 'mqtts://user:pass@locahost:8883' |
|
31 |
+ 'ssl' => :TLSv1, |
|
32 |
+ 'ca_file' => './ca.pem', |
|
33 |
+ 'cert_file' => './client.crt', |
|
34 |
+ 'key_file' => './client.key', |
|
35 |
+ 'topic' => 'huginn' |
|
36 |
+ } |
|
37 |
+ </code></pre> |
|
38 |
+ |
|
39 |
+ Subscribe to CloCkWeRX's TheThingSystem instance (thethingsystem.com), where |
|
40 |
+ temperature and other events are being published. |
|
41 |
+ |
|
42 |
+ <pre><code>{ |
|
43 |
+ 'uri' => 'mqtt://kcqlmkgx:sVNoccqwvXxE@m10.cloudmqtt.com:13858' |
|
44 |
+ 'topic' => 'the_thing_system/demo' |
|
45 |
+ } |
|
46 |
+ </code></pre> |
|
47 |
+ |
|
48 |
+ Subscribe to all topics |
|
49 |
+ <pre><code>{ |
|
50 |
+ 'uri' => 'mqtt://kcqlmkgx:sVNoccqwvXxE@m10.cloudmqtt.com:13858' |
|
51 |
+ 'topic' => '/#' |
|
52 |
+ } |
|
53 |
+ </code></pre> |
|
54 |
+ |
|
55 |
+ Find out more detail on [subscription wildcards](http://www.eclipse.org/paho/files/mqttdoc/Cclient/wildcard.html) |
|
56 |
+ |
|
57 |
+ MD |
|
58 |
+ |
|
59 |
+ def validate_options |
|
60 |
+ # unless options['uid'].present? && |
|
61 |
+ # options['expected_update_period_in_days'].present? |
|
62 |
+ # errors.add(:base, "expected_update_period_in_days and uid are required") |
|
63 |
+ # end |
|
64 |
+ end |
|
65 |
+ |
|
66 |
+ def working? |
|
67 |
+ !recent_error_logs? |
|
68 |
+ end |
|
69 |
+ |
|
70 |
+ def default_options |
|
71 |
+ { |
|
72 |
+ 'uri' => 'mqtts://user:pass@locahost:8883', |
|
73 |
+ 'ssl' => :TLSv1, |
|
74 |
+ 'ca_file' => './ca.pem', |
|
75 |
+ 'cert_file' => './client.crt', |
|
76 |
+ 'key_file' => './client.key', |
|
77 |
+ 'topic' => 'huginn' |
|
78 |
+ } |
|
79 |
+ end |
|
80 |
+ |
|
81 |
+ def mqtt_client |
|
82 |
+ client = MQTT::Client.new(options['uri']) |
|
83 |
+ |
|
84 |
+ if options['ssl'] |
|
85 |
+ client.ssl = options['ssl'].to_sym |
|
86 |
+ client.ca_file = options['ca_file'] |
|
87 |
+ client.cert_file = options['cert_file'] |
|
88 |
+ client.key_file = options['key_file'] |
|
89 |
+ end |
|
90 |
+ |
|
91 |
+ client |
|
92 |
+ end |
|
93 |
+ |
|
94 |
+ def receive(incoming_events) |
|
95 |
+ mqtt_client.connect do |c| |
|
96 |
+ incoming_events.each do |event| |
|
97 |
+ c.publish(options['topic'], payload) |
|
98 |
+ end |
|
99 |
+ end |
|
100 |
+ end |
|
101 |
+ |
|
102 |
+ |
|
103 |
+ def check |
|
104 |
+ mqtt_client.connect do |c| |
|
105 |
+ c.get(options['topic']) do |topic,message| |
|
106 |
+ create_event :payload => { 'topic' => topic, 'message' => message, 'time' => Time.now.to_i } |
|
107 |
+ end |
|
108 |
+ end |
|
109 |
+ end |
|
110 |
+ |
|
111 |
+ end |
|
112 |
+end |